<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>webgl矩阵平移</title>
    <script src="lib/webgl-debug.js"></script>
    <script src="lib/webgl-utils.js"></script>
    <script src="lib/cuon-utils.js"></script>
    <script src="lib/cuon-matrix.js"></script>
</head>

<body onload="main()">
    <canvas width="800" height="800" id="canvas"></canvas>
</body>
<script>
    var vs = `
    attribute vec4 position;
    uniform mat4 formMatrix;
    void main(){
        gl_Position =formMatrix* position;
    }
    `;
    var fs = `
    precision mediump float;
    uniform vec4 fragColor;

    void main(){
        gl_FragColor = fragColor;
    }
    `;
    var canvas;
    var angle = 60;
    var tx = 0.0,
        ty = 0.0,
        tz = 0.0;
    var sx = 1.0,
        sy = 1.0,
        sz = 1.0;
    var gl;

    function main() {
        canvas = document.getElementById("canvas");
        init();
        run();

        setInterval(function() {
            angle++;
            run();
        }, 30);
    }

    function init() {
        if (!canvas) {
            console.log("找不到画布");
            return;
        }

        //获取上下文对象
        gl = canvas.getContext("webgl");

        //初始化着色器
        if (!initShader(gl, vs, fs)) {
            console.log("初始化着色器失败");
            return;
        }

        var n = initVertex(gl);
        if (n < 0) {
            console.log("无法获取顶点相关信息");
            return;
        }



    }


    function run() {
        var radin = Math.PI * angle / 180;
        var cosB = Math.cos(radin);
        var sinB = Math.sin(radin);

        var matrix = new Float32Array([
            cosB * sx, sinB * sx, 0.0, 0.0, -sinB * sy, cosB * sy, 0.0, 0.0,
            0.0, 0.0, 1.0 * sz, 0.0,
            tx, ty, tz, 1.0
        ]);



        var mat = gl.getUniformLocation(gl.program, "formMatrix");
        gl.uniformMatrix4fv(mat, false, matrix);


        var fragColor = gl.getUniformLocation(gl.program, "fragColor");
        // 设置颜色
        gl.uniform4f(fragColor, 0.1, 0.1, 1, 1);



        gl.clearColor(0, 0, 0, 1);
        gl.clear(gl.COLOR_BUFFER_BIT);
        gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
    }

    function initVertex(gl) {
        var verties = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5]);
        var n = 4;
        //创建缓冲区
        var vertexBuffer = gl.createBuffer();
        //绑定缓冲区
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        //向缓冲区写入数据
        gl.bufferData(gl.ARRAY_BUFFER, verties, gl.STATIC_DRAW);
        //获取着色器的属性
        var position = gl.getAttribLocation(gl.program, "position");
        //将缓冲区分配到指定的属性
        gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);
        //关闭缓冲区
        gl.enableVertexAttribArray(position);
        return n;
    }

    // 初始化着色器
    function initShader(gl, vs, fs) {
        var vShader = loadShader(gl, gl.VERTEX_SHADER, vs);
        var fShader = loadShader(gl, gl.FRAGMENT_SHADER, fs);
        if (!vShader || !fShader) {
            return null;
        }
        // 创建程序对象
        var program = gl.createProgram();
        if (!program) {
            console.log("创建程序对象失败");
            return null;
        }
        //将着色器分配到 program
        gl.attachShader(program, vShader);
        gl.attachShader(program, fShader);
        //将着色器连接到对象
        gl.linkProgram(program);
        // 获取连接状态
        var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
        if (!linked) {
            //获取程序信息日志
            var error = gl.getProgramInfoLog(program);
            console.log("程序连接失败：" + error);
            //删除程序和着色器
            gl.deleteProgram(program);
            gl.deleteShader(vShader);
            gl.deleteShader(fShader);
            return null;
        }

        //使用程序
        gl.useProgram(program);
        gl.program = program;
        return program;
    }

    document.addEventListener("keyup", function(event) {
        switch (event.keyCode) {

            case 37:
                tx -= 0.5;
                break;
            case 38:
                ty += 0.5;

                break;
            case 39:
                tx += 0.5;

                break;
            case 40:
                ty -= 0.5;
                break;
            case 87:
                sy += 0.5;
                break;
            case 83:
                sy -= 0.5;
                break;
            case 65:
                sx -= 0.5;
                break;
            case 68:
                sx += 0.5;

                break;
        }
    });

    function loadShader(gl, type, source) {
        // 创建着色器对象
        var shader = gl.createShader(type);
        //引入着色器源代码
        gl.shaderSource(shader, source);
        // 编译着色器
        gl.compileShader(shader);
        //获取编译状态
        var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
        if (!compiled) {
            // 获取着色器信息日志
            var error = gl.getShaderInfoLog(shader);
            console.log("编译着色器失败error:" + error);
            return null;
        }
        return shader;
    }
</script>

</html>